Skip to content

fix(cron): close codex app-server session in teardown to prevent subprocess leak (#62101) - #62105

Open
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-62101
Open

liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-62101

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes a subprocess leak in cron jobs when using the codex_app_server runtime. Each scheduled cron run creates a new ephemeral agent, which spawns a codex app-server subprocess. The subprocess should be cleaned up when the job finishes, but agent.close() does not include _codex_session cleanup. This caused one leaked codex app-server subprocess per cron run until the gateway is restarted.

The fix adds a close_codex_session() helper in agent/codex_runtime.py (idempotent, safe to call multiple times) and calls it from cron's _teardown_cron_agent() function in the finally block after agent.close().

Related Issue

Fixes #62101

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • agent/codex_runtime.py: Add close_codex_session() helper function that safely closes the Codex app-server session if it exists
  • cron/scheduler.py: Call close_codex_session() in _teardown_cron_agent() after agent.close() to prevent subprocess leaks

How to Test

  1. Configure provider: openai-codex with openai_runtime: codex_app_server
  2. Create a recurring cron job: hermes cron create "0 8,13,18 * * *" "echo test"
  3. Start the gateway: hermes gateway --platform telegram
  4. Wait for a few scheduled runs to complete
  5. Check for leaked codex app-server processes: ps -axo pid,ppid,lstart,command | grep "codex app-server"
  6. Expected result: No codex app-server subprocesses remain after each cron job completes

Observed result: The issue reporter verified locally that after this patch, a manual hermes cron run leaves no codex app-server process behind once the job completes.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 26.5 (arm64)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

…rocess leak (NousResearch#62101)

Ephemeral cron agents leak the codex app-server subprocess because
agent.close() does not cleanup _codex_session. This adds a cleanup
helper in codex_runtime.py and calls it from cron's _teardown_cron_agent().
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management codex P3 Low — cosmetic, nice to have labels Jul 10, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the focused cron cleanup. The premise is confirmed on current main: agent/codex_runtime.py:325 creates a per-agent app-server session, while cron/scheduler.py:3372-3385 tears down cron agents through agent.close() without closing that session.

Problems

  • The diff at 7313d61c62a2 changes only agent/codex_runtime.py and cron/scheduler.py; it adds no regression test. Existing teardown-order coverage in tests/cron/test_run_one_job.py:165-205 verifies delivery before agent.close() but does not exercise a Codex session.

Suggested changes

  • Add a cron teardown regression that asserts _teardown_cron_agent() closes and clears an attached _codex_session, including when agent.close() raises. This validates the exact lifecycle path changed here.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 11, 2026
@teknium1 teknium1 added the area/sessions Session lifecycle, resume, persistence, history label Jul 19, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history codex comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: cron jobs leak one codex app-server subprocess per run inside the gateway (codex_app_server runtime)

3 participants